From 6e159fba3f0236fbcc65ba89f12cf07425b1f7aa Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Tue, 21 Mar 2006 11:28:03 +0100 Subject: [PATCH] New SMP IPI interface function called on_selected_cpus(), currently implemented only for x86. The x86 implementation of smp_call_function has been simplified and is now based on on_slected_cpus(). Signed-off-by: Nitin A Kamble Signed-off-by: Keir Fraser --- xen/arch/x86/smp.c | 40 ++++++++++++++++++++++-------------- xen/include/xen/smp.h | 48 ++++++++++++++++++++++++++++--------------- 2 files changed, 56 insertions(+), 32 deletions(-) diff --git a/xen/arch/x86/smp.c b/xen/arch/x86/smp.c index 3154473f26..690bf3121f 100644 --- a/xen/arch/x86/smp.c +++ b/xen/arch/x86/smp.c @@ -266,7 +266,7 @@ void smp_send_event_check_mask(cpumask_t mask) } /* - * Structure and data for smp_call_function(). + * Structure and data for smp_call_function()/on_selected_cpus(). */ struct call_data_struct { @@ -275,41 +275,48 @@ struct call_data_struct { int wait; atomic_t started; atomic_t finished; + cpumask_t selected; }; -static spinlock_t call_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(call_lock); static struct call_data_struct *call_data; -/* - * Run a function on all other CPUs. - * @func: The function to run. This must be fast and non-blocking. - * @info: An arbitrary pointer to pass to the function. - * @wait: If true, spin until function has completed on other CPUs. - * Returns: 0 on success, else a negative status code. - */ int smp_call_function( - void (*func) (void *info), void *info, int unused, int wait) + void (*func) (void *info), + void *info, + int retry, + int wait) +{ + cpumask_t allbutself = cpu_online_map; + cpu_clear(smp_processor_id(), allbutself); + return on_selected_cpus(allbutself, func, info, retry, wait); +} + +extern int on_selected_cpus( + cpumask_t selected, + void (*func) (void *info), + void *info, + int retry, + int wait) { struct call_data_struct data; - unsigned int nr_cpus = num_online_cpus() - 1; + unsigned int nr_cpus = cpus_weight(selected); ASSERT(local_irq_is_enabled()); - if ( nr_cpus == 0 ) - return 0; - data.func = func; data.info = info; data.wait = wait; atomic_set(&data.started, 0); atomic_set(&data.finished, 0); + data.selected = selected; spin_lock(&call_lock); call_data = &data; wmb(); - send_IPI_allbutself(CALL_FUNCTION_VECTOR); + send_IPI_mask(selected, CALL_FUNCTION_VECTOR); while ( atomic_read(wait ? &data.finished : &data.started) != nr_cpus ) cpu_relax(); @@ -353,6 +360,9 @@ fastcall void smp_call_function_interrupt(struct cpu_user_regs *regs) ack_APIC_irq(); perfc_incrc(ipis); + if ( !cpu_isset(smp_processor_id(), call_data->selected) ) + return; + if ( call_data->wait ) { (*func)(info); diff --git a/xen/include/xen/smp.h b/xen/include/xen/smp.h index f64c5b056d..cefce3ff3f 100644 --- a/xen/include/xen/smp.h +++ b/xen/include/xen/smp.h @@ -45,33 +45,35 @@ extern void smp_cpus_done(unsigned int max_cpus); * Call a function on all other processors */ extern int smp_call_function( - void (*func) (void *info), void *info, int retry, int wait); + void (*func) (void *info), + void *info, + int retry, + int wait); + +/* + * Call a function on a selection of processors + */ +extern int on_selected_cpus( + cpumask_t selected, + void (*func) (void *info), + void *info, + int retry, + int wait); /* * Call a function on all processors */ -static inline int on_each_cpu(void (*func) (void *info), void *info, - int retry, int wait) +static inline int on_each_cpu( + void (*func) (void *info), + void *info, + int retry, + int wait) { int ret = smp_call_function(func, info, retry, wait); func(info); return ret; } -extern volatile unsigned long smp_msg_data; -extern volatile int smp_src_cpu; -extern volatile int smp_msg_id; - -#define MSG_ALL_BUT_SELF 0x8000 /* Assume <32768 CPU's */ -#define MSG_ALL 0x8001 - -#define MSG_INVALIDATE_TLB 0x0001 /* Remote processor TLB invalidate */ -#define MSG_STOP_CPU 0x0002 /* Sent to shut down slave CPU's - * when rebooting - */ -#define MSG_RESCHEDULE 0x0003 /* Reschedule request from master CPU*/ -#define MSG_CALL_FUNCTION 0x0004 /* Call function on all other CPUs */ - /* * Mark the boot cpu "online" so that it can call console drivers in * printk() and can access its per-cpu storage. @@ -93,6 +95,18 @@ void smp_prepare_boot_cpu(void); #define num_booting_cpus() 1 #define smp_prepare_boot_cpu() do {} while (0) +static inline int on_selected_cpus( + cpumask_t selected, + void (*func) (void *info), + void *info, + int retry, + int wait) +{ + if ( cpu_isset(0, selected) ) + func(info); + return 0; +} + #endif #define smp_processor_id() raw_smp_processor_id() -- 2.30.2